home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / tahoe-pinsn.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  5KB  |  224 lines

  1. /*
  2.  * Ported by the State University of New York at Buffalo by the Distributed
  3.  * Computer Systems Lab, Department of Computer Science, 1991.
  4.  */
  5.  
  6. #include <stdio.h>
  7.  
  8. #include "defs.h"
  9. #include "param.h"
  10. #include "symtab.h"
  11. #include "tahoe-opcode.h"
  12.  
  13. /* Tahoe instructions are never longer than this.  */
  14. #define MAXLEN 62
  15.  
  16. /* Number of elements in the opcode table.  */
  17. #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
  18.  
  19. extern char *reg_names[];
  20.  
  21. static unsigned char *print_insn_arg ();
  22.  
  23. /* Print the Tahoe instruction at address MEMADDR in debugged memory,
  24.    on STREAM.  Returns length of the instruction, in bytes.  */
  25.  
  26. int
  27. print_insn (memaddr, stream)
  28.      CORE_ADDR memaddr;
  29.      FILE *stream;
  30. {
  31.   unsigned char buffer[MAXLEN];
  32.   register int i;
  33.   register unsigned char *p;
  34.   register char *d;
  35.  
  36.   read_memory (memaddr, buffer, MAXLEN);
  37.  
  38.   for (i = 0; i < NOPCODES; i++)
  39.     if (votstrs[i].detail.code == buffer[0]
  40.     || votstrs[i].detail.code == *(unsigned short *)buffer)
  41.       break;
  42.  
  43.   /* Handle undefined instructions.  */
  44.   if (i == NOPCODES)
  45.     {
  46.       fprintf (stream, "0%o", buffer[0]);
  47.       return 1;
  48.     }
  49.  
  50.   fprintf (stream, "%s", votstrs[i].name);
  51.  
  52.   /* Point at first byte of argument data,
  53.      and at descriptor for first argument.  */
  54.   p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
  55.   d = votstrs[i].detail.args;
  56.  
  57.   if (*d)
  58.     fputc ('\t', stream);
  59.  
  60.   while (*d)
  61.     {
  62.       p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
  63.       d += 2;
  64.       if (*d)
  65.     fprintf (stream, ",");
  66.     }
  67.   return p - buffer;
  68. }
  69. /*******************************************************************/
  70. static unsigned char *
  71. print_insn_arg (d, p, addr, stream)
  72.      char *d;
  73.      register char *p;
  74.      CORE_ADDR addr;
  75.      FILE *stream;
  76. {
  77.   int temp1 = 0;
  78.   register int regnum = *p & 0xf;
  79.   float floatlitbuf;
  80.  
  81.   if (*d == 'b')
  82.     {
  83.       if (d[1] == 'b')
  84.     fprintf (stream, "0x%x", addr + *p++ + 1);
  85.       else
  86.     {
  87.  
  88.       temp1 = *p;
  89.       temp1 <<= 8;
  90.       temp1 |= *(p + 1);
  91.       fprintf (stream, "0x%x", addr + temp1 + 2);
  92.       p += 2;
  93.     }
  94.     }
  95.   else
  96.     switch ((*p++ >> 4) & 0xf)
  97.       {
  98.       case 0:
  99.       case 1:
  100.       case 2:
  101.       case 3:            /* Liter>al(short immediate byte) mode */
  102.     if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
  103.       {
  104.         *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
  105.         fprintf (stream, "$%f", floatlitbuf);
  106.       }
  107.     else
  108.       fprintf (stream, "$%d", p[-1] & 0x3f);
  109.     break;
  110.  
  111.       case 4:            /* Indexed */
  112.     p = (char *) print_insn_arg (d, p, addr + 1, stream);
  113.     fprintf (stream, "[%s]", reg_names[regnum]);
  114.     break;
  115.  
  116.       case 5:            /* Register */
  117.     fprintf (stream, reg_names[regnum]);
  118.     break;
  119.  
  120.       case 7:            /* Autodecrement */
  121.     fputc ('-', stream);
  122.       case 6:            /* Register deferred */
  123.     fprintf (stream, "(%s)", reg_names[regnum]);
  124.     break;
  125.  
  126.       case 9:                    /* Absolute Address & Autoincrement deferred */
  127.     fputc ('*', stream);
  128.     if (regnum == PC_REGNUM)
  129.       {
  130.         temp1 = *p;
  131.         temp1 <<= 8;
  132.         temp1 |= *(p +1);
  133.  
  134.         fputc ('$', stream);
  135.         print_address (temp1, stream);
  136.         p += 4;
  137.         break;
  138.       }
  139.       case 8:            /*Immediate & Autoincrement SP */
  140.         if (regnum == 8)         /*88 is Immediate Byte Mode*/
  141.       fprintf (stream, "$%d", *p++);
  142.  
  143.     else if (regnum == 9)        /*89 is Immediate Word Mode*/
  144.       {
  145.         temp1 = *p;
  146.         temp1 <<= 8; 
  147.         temp1 |= *(p +1);
  148.         fprintf (stream, "$%d", temp1);
  149.         p += 2;
  150.       }  
  151.  
  152.     else if (regnum == PC_REGNUM)    /*8F is Immediate Long Mode*/
  153.       {
  154.         temp1 = *p;
  155.         temp1 <<=8;
  156.         temp1 |= *(p +1);
  157.         temp1 <<=8;
  158.         temp1 |= *(p +2);
  159.         temp1 <<= 8;
  160.         temp1 |= *(p +3);
  161.         fprintf (stream, "$%d", temp1);
  162.         p += 4;
  163.       }
  164.  
  165.     else                            /*8E is Autoincrement SP Mode*/
  166.           fprintf (stream, "(%s)+", reg_names[regnum]);
  167.     break;
  168.  
  169.       case 11:            /* Register + Byte Displacement Deferred Mode*/
  170.     fputc ('*', stream);
  171.       case 10:            /* Register + Byte Displacement Mode*/
  172.     if (regnum == PC_REGNUM)
  173.       print_address (addr + *p + 2, stream);
  174.     else
  175.       fprintf (stream, "%d(%s)", *p, reg_names[regnum]);
  176.     p += 1;
  177.     break;
  178.  
  179.       case 13:            /* Register + Word Displacement Deferred Mode*/
  180.     fputc ('*', stream);
  181.       case 12:            /* Register + Word Displacement Mode*/
  182.     temp1 = *p;
  183.     temp1 <<= 8;
  184.     temp1 |= *(p +1);
  185.     if (regnum == PC_REGNUM)
  186.       print_address (addr + temp1 + 3, stream);
  187.     else
  188.       fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
  189.     p += 2;
  190.     break;
  191.  
  192.       case 15:            /* Register + Long Displacement Deferred Mode*/
  193.     fputc ('*', stream);
  194.       case 14:            /* Register + Long Displacement Mode*/
  195.     temp1 = *p;
  196.     temp1 <<= 8;
  197.     temp1 |= *(p +1);
  198.     temp1 <<= 8;
  199.     temp1 |= *(p +2);
  200.     temp1 <<= 8;
  201.     temp1 |= *(p +3);
  202.     if (regnum == PC_REGNUM)
  203.       print_address (addr + temp1 + 5, stream);
  204.     else
  205.       fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
  206.     p += 4;
  207.       }
  208.  
  209.   return (unsigned char *) p;
  210. }
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.